<template>
    <!-- 报表设计器 -->
    <el-container class="report-design">
        <el-aside class="silder-design-aside" width="240px">
            <silder-design></silder-design>
        </el-aside>
        <el-container class="centerBox">
            <el-header class="report-title" height="49px">
                <div class="title">
                    <div v-if="titleUse" class="text" @click="editTitle()">{{ reportData.title }}</div>
                    <el-input v-else ref="titleInput" v-model.trim="reportData.title" placeholder="请输入报表标题" clearable @blur="titleInputBlur"></el-input>
                </div>
                <div class="">
                    <el-button type="primary" icon="el-icon-view" size="mini" @click.stop="previewReportData()">预览效果</el-button>
                    <el-popconfirm title="是否生成模版？" @confirm="saveTemplate" class="popconfirm">
                        <el-button slot="reference" icon="el-icon-document-checked" type="primary" size="mini">保存模版</el-button>
                    </el-popconfirm>
                    <el-popover placement="left" width="440" trigger="click" class="popconfirm" @show="templateShow">
                        <yi-table ref="templateTable" :data="templateTable.data" :total="templateTable.total" isMounted @getData="templateGetData" :option="{ current: 'pageSize', page: 'pageNum' }" max-height="230px">
                            <el-table-column label="模版名称" prop="title"></el-table-column>
                            <el-table-column label="操作" width="160">
                                <template slot-scope="{ row }">
                                    <el-button type="text" @click.stop="renderTemplate(row)">预览</el-button>
                                    <el-popconfirm title="是否引用模版，模版数据将替换当前所有视图数据？" @confirm="quoteTemplate(row)" class="marginLeft10">
                                        <el-button slot="reference" type="text">引用</el-button>
                                    </el-popconfirm>
                                    <el-popconfirm title="是否引用模版，将模版数据将追加至视图数据？" @confirm="pushTemplate(row)" class="marginLeft10">
                                        <el-button slot="reference" type="text">追加</el-button>
                                    </el-popconfirm>
                                    <el-popconfirm title="是否删除该模版数据？" @confirm="deleteTemplate(row)" class="marginLeft10">
                                        <el-button slot="reference" type="text">删除</el-button>
                                    </el-popconfirm>
                                </template>
                            </el-table-column>
                        </yi-table>
                        <el-button slot="reference" icon="el-icon-document-add" type="primary" size="mini">引用模版</el-button>
                    </el-popover>
                    <el-button class="popconfirm" icon="el-icon-plus" type="primary" size="mini" @click.stop="saveReport()">保存</el-button>
                    <el-button type="primary" icon="el-icon-upload" size="mini" @click.stop="releaseReportData()">发布</el-button>
                    <el-popconfirm title="是否清空当前所有数据？" @confirm="clearReport" class="popconfirm">
                        <el-button slot="reference" type="primary" icon="el-icon-document-delete" size="mini">清空内容</el-button>
                    </el-popconfirm>
                    <el-popconfirm title="是否关闭报表设计？" @confirm="close" class="popconfirm">
                        <el-button slot="reference" size="mini" icon="el-icon-close">关闭</el-button>    
                    </el-popconfirm>
                </div>
            </el-header>
            <el-header class="report-toolbar" height="36px">
                <report-toolbar :selectItem="selectItem"></report-toolbar>
            </el-header>
            <el-main>
                <design-editor ref="designEditor" :reportData="reportData" :selectItem.sync="selectItem"></design-editor>
            </el-main>
        </el-container>
        <el-aside class="prop-design-aside" width="340px">
            <prop-design :selectItem.sync="selectItem" :reportData="reportData" :temporaryBind="temporaryBind" @save="saveReport"></prop-design>
        </el-aside>
        <!-- 预览组件 -->
        <yi-dialog title="预览"
            class="render-dialog"
            width="1000px"
            fullscreen
            :visible.sync="dialogVisible"
            :loading.sync="dialogLoading">
            <report-render ref="reportRender"></report-render>
        </yi-dialog>
    </el-container>
</template>

<script>
import { SilderDesign, DesignEditor, PropDesign, ReportToolbar, ReportRender } from "./components/index";
import { insertCustomReport, selectCustomReportPageLike, deleteCustomReport, selectCustomReportByIds, updateCustomReport } from "@/api/ReportDesign/ReportDesign.js";
import { warning, success } from "@/utils/errorInfo";
import { updateData } from '@/api/system/dict/data';
export default {
    name: "ReportDesign",
    components: {
        SilderDesign,
        DesignEditor,
        PropDesign,
        ReportToolbar,
        ReportRender
    },
    data() {
        return {
            id: null,
            reportData: {
                title: "未定义", // 报表标题
                remark: "", // 备注
                Api: { // Api 配置
                    options: [
                        {
                            disabled: false,
                            api: "", // api 地址
                            method: "get", // get/post 方法
                            structure: "object", // 数据结构
                            params: [], // 参数
                            returnKey: [], // 返回值
                            isReturnKey: false // 隐藏功能
                        }
                    ]
                },
                bindDict: { // 报表分组配置
                    options: [], // 分组字典配置对象
                    lazy: false // 懒加载报表
                },
                reportOption: { // 报表配置
                    reportRenderingType: 'normal', // 报表渲染方式(normal/lazy/multipage)
                    api: '', // multipage 时 接口api地址
                    plugInID: "" // 插件ID（积木报表ID）
                },
                previewOption: {
                    mode: "preview", // 渲染模式
                },
                elementItems: [] // 元素数据
            },
            selectItem: {}, // 选择的元素
            titleUse: true,
            // 预览功能
            dialogVisible: false,
            dialogLoading: false,
            // 模版引用
            templateTable: {
                data: [],
                total: 0
            },
            // 临时绑定报表ID
            temporaryBind: {
                options: []
            }
        }
    },
    methods: {
        editTitle() { // 编辑标题
            this.titleUse = false;
            this.$nextTick(() => {
                this.$refs.titleInput.focus();
            })
        },
        titleInputBlur() { // 失去焦点
            this.titleUse = true;
            if (!this.reportData.title) this.reportData.title = '未定义'; 
        },
        previewReportData() { // 预览
            this.dialogVisible = true;
            this.$nextTick(() => {
                this.$refs.reportRender.render(this.reportData);
            })
        },
        saveTemplate() { // 添加模版
            if (this.reportData.title != '未定义') {
                insertCustomReport({
                    reportType: 1, // 模版
                    title: this.reportData.title,
                    content: JSON.stringify(this.reportData)
                }).then((res) => {
                    success('保存模版成功');
                })
            } else warning('请修改默认名称');
        },
        templateGetData({ pageSize, pageNum }) { // 模版列表
            selectCustomReportPageLike({ reportType: 1, pageSize, pageNum }).then((res) => {
                this.templateTable.data = res?.rows || [];
                this.templateTable.total = res?.total || 0;
                this.$refs.templateTable.loading = false;
            })
        },
        templateShow() { // 引用模版show函数
            this.$nextTick(() => {
                this.$refs.templateTable.refresh();
            })
        },
        quoteTemplate(row) { // 引用模版
            let reportData = JSON.parse(row.content);
            this.selectItem = {};
            this.reportData.elementItems.length = 0;
            this.reportData.elementItems = reportData.elementItems || [];
            this.reportData.previewOption = reportData.previewOption || { mode: 'preview' };
            this.reportData.Api.options.length = 0;
            this.reportData.Api.options = reportData.Api.options || [];
            this.$nextTick(() => {
                this.selectItem = this.reportData.elementItems[0];
            });
        },
        pushTemplate(row) { // 追加模版
            let reportData = JSON.parse(row.content);
            reportData.elementItems.forEach(item => this.reportData.elementItems.push(item));
        },
        renderTemplate(row) { // 渲染模版数据
            let reportData = JSON.parse(row.content);
            this.dialogVisible = true;
            this.$nextTick(() => {
                this.$refs.reportRender.render(reportData);
            })
        },
        deleteTemplate(row) { // 删除模版
            deleteCustomReport([row.id]).then((res) => {
                success('删除成功');
                this.$refs.templateTable.refresh();
            });
        },
        saveReport() { // 保存
            if (this.reportData.title != '未定义') {
                this.reportData.Api.options.forEach(item => {
                    if (item.data) item.data = null;
                });
                if (this.id) { // 编辑状态
                    updateCustomReport({
                        id: this.id,
                        reportType: 0, // 报表
                        title: this.reportData.title,
                        content: JSON.stringify(this.reportData),
                        remark: this.reportData.remark
                    }).then(() => {
                        success('修改成功');
                    })
                } else {
                    insertCustomReport({
                        reportType: 0, // 报表
                        title: this.reportData.title,
                        content: JSON.stringify(this.reportData),
                        remark: this.reportData.remark
                    }).then((res) => {
                        success('保存成功');
                        // 如果配置绑定报表ID 则处理接口相关内容
                        this.handleBind(res.data);
                    })
                }
            } else warning('请修改默认名称');
        },
        releaseReportData() { // 发布
            if (this.reportData.title != '未定义' && this.reportData.bindDict.options.length > 0) {
                this.reportData.Api.options.forEach(item => {
                    if (item.data) item.data = null;
                });
                if (this.id) { // 编辑状态
                    updateCustomReport({
                        id: this.id,
                        reportType: 0, // 报表
                        title: this.reportData.title,
                        status: 2,
                        content: JSON.stringify(this.reportData),
                        remark: this.reportData.remark
                    }).then(() => {
                        success('发布成功');
                    });
                } else {
                    insertCustomReport({
                        reportType: 0, // 报表
                        title: this.reportData.title,
                        status: 2,
                        content: JSON.stringify(this.reportData),
                        remark: this.reportData.remark
                    }).then((res) => {
                        success('发布成功');
                        // 如果配置绑定报表ID 则处理接口相关内容
                        this.handleBind(res.data);
                    })
                }
            } else {
                if (this.reportData.title == '未定义') warning('请修改默认名称');
                else warning('请在报表配置中绑定分组');
            }
        },
        clearReport() { // 清空所有数据
            this.$refs.designEditor.editorInit();
        },
        selectCustomReportByIds(id, status) { // 详情
            selectCustomReportByIds([id], { status }).then((res) => {
                let data = res?.data || [];
                if (data.length > 0) {
                    let reportData = data[0] || {};
                    let content = JSON.parse(reportData.content);
                    this.reportData.title = reportData.title;
                    this.reportData.remark = reportData.remark;
                    this.reportData.elementItems = content.elementItems || [];
                    this.reportData.Api = content.Api || {};
                    this.reportData.bindDict = content.bindDict || {};
                    this.reportData.reportOption = content.reportOption || {};
                    this.reportData.previewOption = content.previewOption || { mode: 'preview' };
                    this.handleDindStatus();
                    this.selectItem = this.reportData.elementItems[0];
                }
            })
        },
        handleBind(data) { // 处理绑定相关内容
            if (this.temporaryBind.options.some(item => item.bindStatus == 0)) {
                let p = [];
                this.temporaryBind.options.forEach(item => {
                    p.push(updateData({
                        dictCode: item.dictCode,
                        dictSort: item.dictSort,
                        dictType: item.dictType,
                        status: item.status,
                        dictLabel: item.dictLabel,
                        dictValue: data.id
                    }).then((res) => res));
                })
                Promise.all(p).then(() => {
                    let time = setTimeout(() => {
                        success('报表ID绑定成功');
                        clearTimeout(time);
                        time = null;
                    }, 2000)
                })
            }
        },
        handleDindStatus() { // 处理绑定状态
            let p = [];
            this.reportData.bindDict.options.length > 0 && this.reportData.bindDict.options.forEach(item => {
                p.push(
                    this.getDicts_promise(item.dictType).then((data) => {
                        let isEffective = data.some(dict => {
                            return dict.dictCode === item.dictCode && dict.dictValue == this.$route.query.id
                        });
                        item.bindStatus = isEffective ? 1 : 2;
                    })
                )
            })
        },
        getDicts_promise(val) { // 获取字典表
            return new Promise((resolve) => {
                this.getDicts(val).then((res) => {
                    let data = res?.data || [];
                    resolve(data);
                });
            })
        },
        close() { // 关闭页面
            let browserName = navigator.appName;
            if (browserName == "Netscape") {
                window.location.href = "about:blank"; //Chrome浏览器必须要有这句话才能正常关闭页面
            } else if (browserName == "Microsoft Internet Explorer") {
                window.opener = null;
            }
            window.close();
        }
    },
    mounted() {
        if (this.$route.query.id) { // 编辑状态
            this.id = this.$route.query.id;
            this.selectCustomReportByIds(this.$route.query.id, this.$route.query.status);
        }
    }
}
</script>

<style>
    @import url('./ReportDesign.css');
    @import url('./icon/iconfont.css');
    @import url('./font/font.css');
</style>